import {
  IDataLoadingStrategy,
  ILoadingContext,
  StandardLoadingStrategy,
} from './sourceLoadingStrategy';
import { ChunkedLoadingStrategy } from './chunkedLoadingStrategy';
import { MapCore } from '../mapCore';

/**
 * 数据加载管理器 - 负责选择和执行合适的数据加载策略
 */
export class SourceLoadingManager {
  private strategies: IDataLoadingStrategy[] = [];

  constructor() {
    // 注册默认策略
    this.registerStrategy(new StandardLoadingStrategy());
    this.registerStrategy(new ChunkedLoadingStrategy());
  }

  /**
   * 注册新的加载策略
   */
  registerStrategy(strategy: IDataLoadingStrategy): void {
    this.strategies.push(strategy);
  }

  /**
   * 移除指定策略
   */
  removeStrategy(
    strategyClass: new (...args: any[]) => IDataLoadingStrategy,
  ): void {
    this.strategies = this.strategies.filter(
      (strategy) => !(strategy instanceof strategyClass),
    );
  }

  /**
   * 选择并执行合适的加载策略
   */
  async loadData(
    sourceId: string,
    source: mapboxgl.GeoJSONSourceSpecification,
    mapCore: MapCore,
    context?: ILoadingContext,
  ): Promise<string> {
    const features = (source.data as any)?.features;
    const featureCount = features?.length || 0;
    const dataSize = JSON.stringify(source).length;

    // 查找第一个适用的策略
    const strategy = this.strategies.find((s) =>
      s.shouldUseStrategy(featureCount, dataSize),
    );

    if (!strategy) {
      throw new Error('没有找到适用的数据加载策略');
    }

    // 记录策略选择信息
    const strategyName = strategy.constructor.name;
    context?.safeLog?.(
      `🎯 选择加载策略: ${strategyName} (${featureCount}个要素, ${(dataSize / 1024 / 1024).toFixed(2)}MB)`,
    );

    return strategy.loadData(sourceId, source, mapCore, context);
  }

  /**
   * 获取当前注册的策略列表
   */
  getStrategies(): IDataLoadingStrategy[] {
    return [...this.strategies];
  }

  /**
   * 预测将使用的策略（用于测试和调试）
   */
  predictStrategy(
    featureCount: number,
    dataSize: number,
  ): IDataLoadingStrategy | null {
    return (
      this.strategies.find((s) =>
        s.shouldUseStrategy(featureCount, dataSize),
      ) || null
    );
  }
}
